package br.edu.unoesc.minibi.webmodule.managedBeans;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;

import org.primefaces.component.chart.series.ChartSeries;
import org.primefaces.model.chart.CartesianChartModel;

import br.edu.unoesc.minibi.VO.AreaPlantadaVO;
import br.edu.unoesc.minibi.VO.ItemVendaProdutoVO;
import br.edu.unoesc.minibi.analisador.Analisador;
import br.edu.unoesc.minibi.analisador.NumberFormat;
import br.edu.unoesc.minibi.model.Cultura;
import br.edu.unoesc.minibi.model.Produto;
import br.edu.unoesc.minibi.service.AreaPlantadaServiceInterface;
import br.edu.unoesc.minibi.service.CulturaServiceInterface;
import br.edu.unoesc.minibi.service.ProdutoServiceInterface;

@ManagedBean(name = "mainManagedBean")
@SessionScoped
public class MainManagedBean {

	@ManagedProperty(value = "#{produtoService}")
	private ProdutoServiceInterface produtoService;

	@ManagedProperty(value = "#{areaPlantadaService}")
	private AreaPlantadaServiceInterface areaPlantadaService;

	@ManagedProperty(value = "#{culturaService}")
	private CulturaServiceInterface culturaService;

	private CartesianChartModel cartesianChartModel;
	private CartesianChartModel cartesianChartModelProduto;
	private CartesianChartModel cartesianChartModelPrevisaoCompra;
	private Produto produtoSelecionado;
	private Cultura culturaSelecionada;

	private Analisador analisador = new Analisador();
	private float variacao = 0f;
	private boolean is_variacao_p_cima = false;

	private Long previsaoAreaPlantada = 0l;
	private boolean is_analisa_valor_usuario;

	// === métodos

	private void createGraficoAreaPlantada() {
		cartesianChartModel = new CartesianChartModel();
		ChartSeries cs = new ChartSeries("Ha plantado");
		ChartSeries csPrevisao = new ChartSeries("Previsão");

		List<AreaPlantadaVO> lista = getListaGrafico();
		Float[] valoresBasePrevisao = new Float[lista.size()];
		int i = 0;

		// forma array de base para previsão
		for (AreaPlantadaVO area : lista) {
			cs.set(area.getAno().toString(), area.getQtdPlantada());
			valoresBasePrevisao[i] = area.getQtdPlantada().floatValue();
			i += 1;
		}

		/**
		 * se o usuário inseriu valores para análise, não leva em conta a
		 * previsão
		 */
		if (!is_analisa_valor_usuario) {
			previsaoAreaPlantada = NumberFormat.arredondaLong(analisador.getPrevisao(valoresBasePrevisao));
		}

		/** bloco para criar segmento de previsão no gráfico */
		AreaPlantadaVO lastArea = lista.get(lista.size() - 1);
		AreaPlantadaVO areaPrevisao = new AreaPlantadaVO(culturaSelecionada.getNome(), previsaoAreaPlantada, lastArea.getAno() + 1);
		csPrevisao.set(lastArea.getAno().toString(), lastArea.getQtdPlantada());
		csPrevisao.set(areaPrevisao.getAno().toString(), areaPrevisao.getQtdPlantada());
		/** fim do bloco para criar segmento de previsão no gráfico */

		/**
		 * analisa qual cor utilizar no segmento conforme a previsão.<br>
		 * Verde: previsão de crescimento - Vermelho: previsão de queda. <br>
		 * deve ser colocado na página via javascript(ver documentação
		 * primefaces)
		 */
		if (lastArea.getQtdPlantada() > areaPrevisao.getQtdPlantada()) {
			float dif = lastArea.getQtdPlantada().floatValue() - areaPrevisao.getQtdPlantada().floatValue();
			variacao = dif / lastArea.getQtdPlantada().floatValue() * 100;
			is_variacao_p_cima = false;
			csPrevisao.setStyle("style_desce");
		} else {
			float dif = areaPrevisao.getQtdPlantada().floatValue() - lastArea.getQtdPlantada().floatValue();
			variacao = dif / areaPrevisao.getQtdPlantada().floatValue() * 100;
			is_variacao_p_cima = true;
			csPrevisao.setStyle("style_sobe");
		}

		cartesianChartModel.addSeries(cs);
		cartesianChartModel.addSeries(csPrevisao);

	}

	private void createGraficoItemVenda() {
		cartesianChartModelProduto = new CartesianChartModel();
		cartesianChartModelPrevisaoCompra = new CartesianChartModel();

		ChartSeries cs = new ChartSeries("Venda");
		ChartSeries csPrevisao = new ChartSeries("Prev. próx. safra");
		ChartSeries csPrevisaoCompra = new ChartSeries("Prev. de compra próx. ano");

		List<ItemVendaProdutoVO> lista = getListaGraficoItemVenda();
		List<ItemVendaProdutoVO> listaCompra = new ArrayList<ItemVendaProdutoVO>();
		int i = 0;

		for (ItemVendaProdutoVO area : lista) {
			cs.set(area.getMes().toString(), area.getTotalVendidoMes());

			/** bloco para montar previsão de venda */
			float vlr = (variacao * area.getTotalVendidoMes().floatValue()) / 100f;
			if (is_variacao_p_cima) {
				csPrevisao.set(area.getMes().toString(), vlr + area.getTotalVendidoMes());
			} else {
				csPrevisao.set(area.getMes().toString(), area.getTotalVendidoMes() - vlr);
			}
			/** fim bloco para montar previsão de venda */

			/** bloco para montar gráfico de compras */
			ItemVendaProdutoVO it_prox = null;
			float vlr_prox = 0f;
			float vlr_atual = 0f;

			try {
				it_prox = lista.get(i + 1);
			} catch (Exception e) {
				it_prox = null;
			}
			if (it_prox != null) {
				vlr_prox = (variacao * it_prox.getTotalVendidoMes().floatValue()) / 100f;
				if (is_variacao_p_cima) {
					vlr_prox += it_prox.getTotalVendidoMes().floatValue();
					vlr_atual = vlr + area.getTotalVendidoMes();
				} else {
					vlr_prox = it_prox.getTotalVendidoMes().floatValue() - vlr_prox;
					vlr_atual = area.getTotalVendidoMes() - vlr;
				}
			}

			if (i % 2 != 0 && i < lista.size() - 1) {
				ItemVendaProdutoVO itemPrevCompra = new ItemVendaProdutoVO(vlr_atual + vlr_prox, null, null, area.getMes());
				listaCompra.add(itemPrevCompra);
			} else {
				ItemVendaProdutoVO itemPrevCompra = new ItemVendaProdutoVO(0f, null, null, area.getMes());
				listaCompra.add(itemPrevCompra);
			}
			i += 1;
		}

		/** ajusta valores para um mês antes */
		for (int j = 0; j < 11; j++) {
			ItemVendaProdutoVO temp = listaCompra.get(j);
			if (temp.getMes() == 1) {
				temp.setMes(12);
			} else {
				temp.setMes(temp.getMes() - 1);
			}
			csPrevisaoCompra.set(temp.getMes().toString(), temp.getTotalVendidoMes());
		}

		/** fim bloco para montar gráfico de compras */

		if (!is_variacao_p_cima) {
			csPrevisao.setStyle("style_desce");
		} else {
			csPrevisao.setStyle("style_sobe");
		}

		cartesianChartModelProduto.addSeries(cs);
		cartesianChartModelProduto.addSeries(csPrevisao);
		cartesianChartModelPrevisaoCompra.addSeries(csPrevisaoCompra);
	}

	public List<ItemVendaProdutoVO> getListaGraficoItemVenda() {
		Calendar cal = Calendar.getInstance();
		cal.setTime(new Date());

		return produtoService.getRelatorioVendaMesAno(produtoSelecionado, cal.get(Calendar.YEAR));
	}

	public List<AreaPlantadaVO> getListaGrafico() {
		return areaPlantadaService.getAreaPlantadaGrafico(culturaSelecionada);
	}

	public void selecionarProduto(Produto produto) {
		this.produtoSelecionado = produto;
	}

	public void selecionarCultura(Cultura cultura) {
		this.culturaSelecionada = cultura;
	}

	public String redirectToAnalise() {
		is_analisa_valor_usuario = false;
		if (culturaSelecionada == null || produtoSelecionado == null) {
			FacesMessage fm = new FacesMessage("Deve-se selecionar um produto e uma cultura para analisar!");
			fm.setSeverity(FacesMessage.SEVERITY_ERROR);
			FacesContext.getCurrentInstance().addMessage(null, fm);

			return "";
		}

		createGraficoAreaPlantada();
		createGraficoItemVenda();
		return "/analise/analisa.java";
	}

	public void criaGraficos() {
		is_analisa_valor_usuario = true;
		createGraficoAreaPlantada();
		createGraficoItemVenda();
	}

	// === get e set

	public ProdutoServiceInterface getProdutoService() {
		return produtoService;
	}

	public void setProdutoService(ProdutoServiceInterface produtoService) {
		this.produtoService = produtoService;
	}

	public AreaPlantadaServiceInterface getAreaPlantadaService() {
		return areaPlantadaService;
	}

	public void setAreaPlantadaService(AreaPlantadaServiceInterface areaPlantadaService) {
		this.areaPlantadaService = areaPlantadaService;
	}

	public CulturaServiceInterface getCulturaService() {
		return culturaService;
	}

	public void setCulturaService(CulturaServiceInterface culturaService) {
		this.culturaService = culturaService;
	}

	public CartesianChartModel getCartesianChartModel() {
		return cartesianChartModel;
	}

	public void setCartesianChartModel(CartesianChartModel cartesianChartModel) {
		this.cartesianChartModel = cartesianChartModel;
	}

	public Produto getProdutoSelecionado() {
		return produtoSelecionado;
	}

	public void setProdutoSelecionado(Produto produtoSelecionado) {
		this.produtoSelecionado = produtoSelecionado;
	}

	public Cultura getCulturaSelecionada() {
		return culturaSelecionada;
	}

	public void setCulturaSelecionada(Cultura culturaSelecionada) {
		this.culturaSelecionada = culturaSelecionada;
	}

	public CartesianChartModel getCartesianChartModelProduto() {
		return cartesianChartModelProduto;
	}

	public void setCartesianChartModelProduto(CartesianChartModel cartesianChartModelProduto) {
		this.cartesianChartModelProduto = cartesianChartModelProduto;
	}

	public CartesianChartModel getCartesianChartModelPrevisaoCompra() {
		return cartesianChartModelPrevisaoCompra;
	}

	public void setCartesianChartModelPrevisaoCompra(CartesianChartModel cartesianChartModelPrevisaoCompra) {
		this.cartesianChartModelPrevisaoCompra = cartesianChartModelPrevisaoCompra;
	}

	public Long getPrevisaoAreaPlantada() {
		return previsaoAreaPlantada;
	}

	public void setPrevisaoAreaPlantada(Long previsaoAreaPlantada) {
		this.previsaoAreaPlantada = previsaoAreaPlantada;
	}

}